// 选取dom节点
const $ = element => document.querySelector(element)

const getNormalTime = data => {
    var date = new Date(+data);//如果date为13位不需要乘1000
    var Y = date.getFullYear()
    var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1)
    var D = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate())
    var h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours())
    var m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes())
    var s = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds())
    return [Y, M, D, h, m, s]
}

const getUnixTime = time => +new Date(time)

const setInputDataFromRange = (inputDomArray, rangeValue) => {
    for (let i = 0; i < inputDomArray.length; i++) {
        inputDomArray[i].value = rangeValue[i]
    }
}

const setRangeDataFromInput = (inputDomArray, domRange) => {
    domRange.value = getUnixTime(setRangeValue(inputDomArray.map(x => x.value)))
}

const setRangeValue = data => {
    const [year, month, day, hour, minute, second] = data
    return `${year}-${month}-${day} ${hour}:${minute}:${second}`
}

const check = (char, domArray) => checkNumber(char) && switchCheckData(domArray)

const checkNumber = char => ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].some(x => Object.is(x, char))

const switchCheckData = domArray => {
    const val = domArray.map(x => x.value)
    switch (true) {
        case val[1] > 12:
        case val[2] > 31:
        case val[3] > 23:
        case val[4] > 59:
        case val[5] > 59:
            return false
        // 年月日非‘00’
        case Object.is(val[1], '00'):
        case Object.is(val[2], '00'):
            return false
        // 小月份
        case ['04', '06', '09', '11'].some(x => Object.is(val[1], x)) && val[2] > 30:
            return false
        // 平年和闰年
        case val[1] === '02' && Object.is(val[0] % 100, 0) && val[2] > 29:
            return false
        case val[1] === '02' && !Object.is(val[0] % 100, 0) && val[2] > 28:
            return false
        default:
            return true
    }
}

const checkInitData = inputDomArray => (range, start, end) => {
    const current = getUnixTime(setRangeValue(inputDomArray.map(x => x.value)))
    if (current > end || current < start) {
        range.value = start
        setInputDataFromRange(inputDomArray, getNormalTime(range.value))
    } else {
        range.value = current
    }
}

const throttle = (fn, threshhold) => {
    var timeout
    var start = new Date;
    var threshhold = threshhold || 160
    return function () {
        var context = this, args = arguments, curr = new Date() - 0
        clearTimeout(timeout)//总是干掉事件回调
        if (curr - start >= threshhold) {
            fn.apply(context, args) //只执行一部分方法，这些方法是在某个时间段内执行一次
            start = curr
        } else {
            //让方法在脱离事件后也能执行一次
            timeout = setTimeout(function () {
                fn.apply(context, args)
            }, threshhold);
        }
    }
}

const toggleClass = (index, targetVal, dom) => {
    if ((index === 0 && targetVal.length < 4) || targetVal.length < 2) {
        dom.classList.add('vilid-fail')
    } else {
        dom.classList.remove('vilid-fail')
    }
}

const init = () => {
    let range = $('#rangeInput')
    let rangeContainer = $('.rangeContainer')
    let start = getUnixTime('2018/07/01')
    let end = getUnixTime('2019/09/12')
    range.min = start
    range.max = end
    range.defaultValue = start // 默认 start 应该是表单输入
    $('#start').innerHTML = setRangeValue(getNormalTime(start))
    $('#end').innerHTML = setRangeValue(getNormalTime(end))
    const inputId = ['#year', '#month', '#day', '#hour', '#minute', '#second']
    const inputDomArray = inputId.map(x => $(x))

    setInputDataFromRange(inputDomArray, getNormalTime(range.value))

    range.addEventListener('mousemove', throttle(e => {
        setInputDataFromRange(inputDomArray, getNormalTime(e.target.value))
    }), false)

    for (let i = 0; i < inputDomArray.length; i++) {
        const inputDom = inputDomArray[i]
        inputDom.addEventListener('input', (e) => {
            if (check(e.data, inputDomArray)) {
                toggleClass(i, e.target.value, rangeContainer)
                // input事件 最后一个表单赋值，其余的切换到下一个表单
                if (Object.is(i + 1, inputDomArray.length)) {
                    // 校验数据
                    checkInitData(inputDomArray)(range, start, end)
                } else if (Object.is(i, 0) && Object.is(e.target.value.length, 4) || !Object.is(i, 0) && Object.is(e.target.value.length, 2)) {
                    inputDomArray[i + 1].focus()
                }
            } else {
                // 校验失败禁止输入该字符
                rangeContainer.classList.add('vilid-fail')
                e.target.value = e.target.value.split(e.data).join('')
            }
        }, false)
        inputDom.addEventListener('blur', (e) => {
            // 如果没有红框就赋值，否则就重置
            if (!rangeContainer.classList.contains('vilid-fail')) {
                checkInitData(inputDomArray)(range, start, end)
            } else {
                rangeContainer.classList.remove('vilid-fail')
                range.value = start
                setInputDataFromRange(inputDomArray, getNormalTime(range.value))
            }
        }, false)
    }

}

init()